package de.gof.ppstool.lagerverwaltung.db;

import static de.gof.ppstool.lagerverwaltung.db.Arbeitsplatz.FINDE_ALLE_ARBEITSPLAETZE;
import static de.gof.ppstool.lagerverwaltung.db.Arbeitsplatz.FINDE_ARBEITSPLATZ_NACH_ID;
import static de.gof.ppstool.lagerverwaltung.db.Arbeitsplatz.PARAM_ARBEITSPLATZ_ID;
import static de.gof.ppstool.lagerverwaltung.db.Teil.FINDE_ALLE_TEILE;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.NoResultException;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

/**
 * LagerverwaltungDAO
 * @author  Marcus
 */
@Repository
@Transactional(propagation = Propagation.MANDATORY)
public class LagerverwaltungDAO implements Serializable, ILagerverwaltungDAO {
	private static final long serialVersionUID = -2698141923742263780L;
	@PersistenceContext
	private EntityManager em;

	/**
	 * { @inheritDoc}
	 */
	@Override
	public Arbeitsplatz erstelleArbeitsplatz(Arbeitsplatz arbeitsplatz) {
		em.persist(arbeitsplatz);
		return arbeitsplatz;
	}

	/**
	 * { @inheritDoc}
	 */
	@Override
	public Teil erstelleTeil(Teil teil) {
		em.persist(teil);
		return teil;
	}

	/**
	 * { @inheritDoc}
	 */
	@Override
	public Arbeitsplatz aendereArbeitsplatz(Arbeitsplatz arbeitsplatz) {
		if (arbeitsplatz == null)
			return arbeitsplatz;

		arbeitsplatz = em.merge(arbeitsplatz);
		return arbeitsplatz;
	}

	/**
	 * { @inheritDoc}
	 */
	@Override
	public Teil aendereTeil(Teil teil) {
		if (teil == null)
			return teil;

		teil = em.merge(teil);
		return teil;
	}

	/**
	 * { @inheritDoc}
	 */
	@Override
	public void loescheArbeitsplatz(Arbeitsplatz arbeitsplatz) {
		if (arbeitsplatz == null)
			return;

		if (!em.contains(arbeitsplatz))
			arbeitsplatz = em.find(Arbeitsplatz.class,
					arbeitsplatz.getArbeitsplatzId());

		em.remove(arbeitsplatz);
	}

	/**
	 * { @inheritDoc}
	 */
	@Override
	public void loescheTeil(Teil teil) {
		if (teil == null)
			return;

		if (!em.contains(teil))
			teil = em.find(Teil.class, teil.getTeilId());

		em.remove(teil);
	}

	/**
	 * { @inheritDoc}
	 * 	 	
	 */
	@Override
	public Teil findeTeilNachTeilId(Long teilId) throws TeilNotFoundException {
		Teil teil = findeTeilNachTeilId2(teilId);
		return teil;
	}

	/**
	 * { @inheritDoc}
	 * 	 	
	 */
	@Override
	public Teil findeTeilNachTeilId2(Long id) throws TeilNotFoundException {
		Query query = em.createNamedQuery(Teil.FINDE_TEIL_NACH_TEIL_ID);
		query.setParameter(Teil.PARAM_TEIL_ID, id);
		Teil t = null;
		try {
			t = (Teil) query.getSingleResult();
		} catch (Exception e) {
			System.out.println("Teil nicht gefunden:  " + id);
			e.printStackTrace();
		}

		if (t == null) {
			final TeilNotFoundException e = new TeilNotFoundException(id);
			throw e;
		}

		return t;
	}

	/**
	 * { @inheritDoc}
	 */
	@Override
	@SuppressWarnings("unchecked")
	public List<Arbeitsplatz> findeAlleArbeitsplaetze()
			throws ArbeitsplatzNotFoundException {
		final Query query = em.createNamedQuery(FINDE_ALLE_ARBEITSPLAETZE);
		List<Arbeitsplatz> arbeitsplaetze = query.getResultList();
		if (arbeitsplaetze == null)
			arbeitsplaetze = new ArrayList<Arbeitsplatz>();

		return arbeitsplaetze;
	}

	/**
	 * { @inheritDoc}
	 */
	@Override
	@SuppressWarnings("unchecked")
	public List<Teil> findeAlleTeile() throws TeilNotFoundException {
		final Query query = em.createNamedQuery(FINDE_ALLE_TEILE);
		List<Teil> teile = query.getResultList();
		if (teile == null)
			teile = new ArrayList<Teil>();

		return teile;
	}

	/**
	 * { @inheritDoc}
	 */
	@Override
	public Arbeitsplatz findeArbeitsplatzNachId(Long arbeitsplatzId)
			throws ArbeitsplatzNotFoundException {
		final Query query = em.createNamedQuery(FINDE_ARBEITSPLATZ_NACH_ID);
		query.setParameter(PARAM_ARBEITSPLATZ_ID, arbeitsplatzId);
		Arbeitsplatz arbeitsplatz = null;
		try {
			arbeitsplatz = (Arbeitsplatz) query.getSingleResult();
		} catch (NoResultException e) {
			final ArbeitsplatzNotFoundException e2 = new ArbeitsplatzNotFoundException(
					arbeitsplatzId);
			//if (DEBUG) end(LOG, e2.getMessage());
			e2.printStackTrace();
		}

		return arbeitsplatz;
	}

	@Override
	@SuppressWarnings("unchecked")
	public List<Teil> findeTeilNachTeileArt(String teilart) {
		final Query query = em.createNamedQuery(Teil.FINDE_TEIL_NACH_ART);
		query.setParameter(Teil.PARAM_TEIL_TEILART, teilart);
		List<Teil> teile = null;
		teile = query.getResultList();
		return teile;
	}

}
